using System;
using System.Data;
using System.IO;
namespace Microsoft.Health.Samples.PatientConnect.TreyResearch.HealthVaultAdapter
{
    /// <summary>
    /// Handles Patients Database
    /// </summary>
    public class PatientDBHandler
    {
        string xmlFilePath = string.Empty;
        DataSet patientDataSet = null;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="patientXmlFilePath">Patients Xml File Path</param>
        public PatientDBHandler(string patientXmlFilePath)
        {
            xmlFilePath = patientXmlFilePath;
            CreateDataSet();
        }

        /// <summary>
        /// Creates Data Set
        /// </summary>
        /// <returns></returns>
        private DataSet CreateDataSet()
        {
            CreatePatientTable();
            if (File.Exists(xmlFilePath))
            {
                patientDataSet.ReadXml(xmlFilePath);
            }
            return patientDataSet;
        }

        /// <summary>
        /// Create Patient table
        /// </summary>
        private void CreatePatientTable()
        {
            patientDataSet = new DataSet("Patients");
            DataTable patientTable = new DataTable("Patient");
            patientTable.Columns.Add(new DataColumn("id", typeof(Guid)));
            patientTable.Columns.Add(new DataColumn("MedicalRecordNumber", typeof(Guid)));
            patientTable.Columns.Add(new DataColumn("LastName", typeof(String)));
            patientTable.Columns.Add(new DataColumn("FirstName", typeof(String)));
            patientTable.Columns.Add(new DataColumn("MiddleName", typeof(String)));
            patientTable.Columns.Add(new DataColumn("YearOfBirth", typeof(String), null, MappingType.Element));
            patientTable.Columns.Add(new DataColumn("Gender", typeof(String)));
            patientTable.Columns.Add(new DataColumn("City", typeof(String)));
            patientTable.Columns.Add(new DataColumn("State", typeof(String)));
            patientTable.Columns.Add(new DataColumn("Country", typeof(String)));
            patientTable.Columns.Add(new DataColumn("Active", typeof(Boolean)));
            patientTable.Columns.Add(new DataColumn("RegisteredWithHealthVault", typeof(Boolean)));
            patientTable.Columns.Add(new DataColumn("HV_Person_ID", typeof(Guid)));
            patientTable.Columns.Add(new DataColumn("HV_Record_ID", typeof(Guid)));
            patientDataSet.Tables.Add(patientTable);
        }

        /// <summary>
        /// Selects the List of patients from patient table
        /// </summary>
        /// <param name="conditions">condition for selection</param>
        /// <returns>List of data rows</returns>
        public DataRow[] SelectPatient(string conditions)
        {
            CreateDataSet();
            DataRow[] patientsRow = patientDataSet.Tables[0].Select(conditions);
            return patientsRow;
        }

        /// <summary>
        /// Adds the patient to data base
        /// </summary>
        /// <param name="id">Patient ID</param>
        /// <param name="medicalRecordNumber">Medical Record Number</param>
        /// <param name="lastName">Last name</param>
        /// <param name="firstName">First name</param>
        /// <param name="middleName">Middle name</param>
        /// <param name="yearOfBirth">Year of birth</param>
        /// <param name="gender">Gender</param>
        /// <param name="city">City</param>
        /// <param name="state">State</param>
        /// <param name="country">Country</param>
        /// <param name="active">Active</param>
        /// <param name="registeredWithHealthVault">Registered with health vault</param>
        /// <param name="hvPersonId">Health vault personId</param>
        /// <param name="hvRecordId">Health vault recordId</param>
        public void AddPatient(Guid id,
                               string medicalRecordNumber,
                               string lastName,
                               string firstName,
                               string middleName,
                               int? yearOfBirth,
                               string gender,
                               string city,
                               string state,
                               string country,
                               bool? active,
                               bool? registeredWithHealthVault,
                               Guid hvPersonId,
                               Guid hvRecordId)
        {
            object[] itemObject = new object[]{
                    id,
                    medicalRecordNumber,
                    lastName,
                    firstName,
                    middleName,
                    yearOfBirth,
                    gender,
                    city,
                    state,
                    country,
                    active,
                    registeredWithHealthVault,
                    hvPersonId,
                    hvRecordId};
            patientDataSet.Tables[0].Rows.Add(itemObject);
        }

        /// <summary>
        /// Update patient
        /// </summary>
        /// <param name="patientRow">patient row</param>
        public void UpdatePatient(DataRow[] patientRow)
        {
            patientDataSet.Merge(patientRow, true, MissingSchemaAction.Add);
            patientDataSet.AcceptChanges();
        }

        /// <summary>
        /// commit patient to database
        /// </summary>
        public void Commit()
        {
            patientDataSet.AcceptChanges();
            patientDataSet.WriteXml(xmlFilePath);
        }
    }
}